// Copyright (C) 1953-2022 NUDT
// Verilog module name - pulse_generation
// Version: V4.0.20221216
// Created:
//         by - fenglin
////////////////////////////////////////////////////////////////////////////
// Description:
//         pulse_generation
///////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ps

module pulse_generation
(
		i_clk,
		i_rst_n,
	//Network input top module
		i_gmii_clk,
		i_gmii_en,
		iv_gmii_data,
		i_gmii_er,
       
		iv_flowid,		
		o_pulse   
);

input					i_clk;
input           		i_rst_n;
input					i_gmii_clk;
input 					i_gmii_en;
input 			[7:0]	iv_gmii_data;
input					i_gmii_er;
input			[13:0]	iv_flowid;
output	reg				o_pulse;

reg 					rdreq;
wire			[7:0]	dcfifo_data;
wire					rdempty;
reg 			[10:0]	tick_count;
reg 			[7:0]	rv_ethtype;
reg				[13:0]	flowid_pre_reg;

reg				[3:0]	pug_state;
localparam				idle				= 4'd0,
						delay		        = 4'd1,
						wait1			    = 4'd2,
						wait2			    = 4'd3,						
						read_start			= 4'd4,
						read_ethtype		= 4'd5,				
						read_flowid		    = 4'd6,						
						pulse_generate_s	= 4'd7,
						read_rest			= 4'd8;
						
always@ (posedge i_clk or negedge i_rst_n)
	if(!i_rst_n) begin
		o_pulse 			<= 1'b0;
		tick_count			<= 11'b0;
		rdreq				<= 1'b0;
		flowid_pre_reg		<= 14'b0;
		rv_ethtype          <= 8'b0;
		pug_state			<= idle;			
	end
	else begin
		case (pug_state)
			idle: begin
				tick_count	<= 11'b0;
				if (!rdempty) begin
					pug_state	<= delay;
				end
				else begin
					pug_state	<= idle;
				end
			end
            delay:begin
                pug_state <= wait1;            
            end 
            wait1:begin
                rdreq     <= 1'b1;
                o_pulse   <= 1'b0;
                pug_state <= wait2;
            end  	
            wait2:begin
                rdreq     <= 1'b1;
                o_pulse   <= 1'b0;
                pug_state <= read_start;
            end  			
			read_start: begin
			    rdreq     <= 1'b1;
				if (dcfifo_data == 8'h55) begin
					tick_count	<= 11'b0;
					pug_state	<= read_start;
				end	
				else if (dcfifo_data == 8'hd5) begin
					tick_count	<= tick_count + 1'b1;
					pug_state	<= read_ethtype;
				end	
				else begin
					tick_count	<= 11'b0;
					pug_state	<= read_rest;
				end
			end		
			read_ethtype: begin
			    rdreq           <= 1'b1;
				tick_count		<= tick_count + 1'b1;
				if (tick_count == 11'd13)begin
					rv_ethtype  <= dcfifo_data;
					pug_state	<= read_ethtype;								
				end
				else if (tick_count == 11'd14) begin
					if({rv_ethtype,dcfifo_data}==16'h8100)begin
						pug_state	<= read_flowid;
					end
					else begin
						pug_state	<= read_rest;
					end								
				end				
				else begin	
					pug_state	<= read_ethtype;				
				end						
			end		
			read_flowid: begin
			    rdreq           <= 1'b1;
				tick_count		<= tick_count + 1'b1;
				if (tick_count == 11'd15) begin	
					flowid_pre_reg[13:8]<= dcfifo_data[5:0];
					pug_state	    <= read_flowid;	
				end
				else if (tick_count == 11'd16) begin	
					flowid_pre_reg[7:0]<= dcfifo_data;
					pug_state	    <= read_flowid;	
				end	
				else if (tick_count == 11'd17)begin	
					pug_state	    <= read_rest;	
					if(flowid_pre_reg== iv_flowid)begin
						o_pulse		<= 1'b1;
					end		
				    else begin
					    o_pulse		<= 1'b0;
					end
				end
				else begin
					pug_state	<= read_rest;
				end							
			end
			read_rest: begin
				o_pulse	<= 1'b0;
				if (!rdempty) begin
					tick_count		<= tick_count + 1'b1;
					pug_state	    <= read_rest;
				end
				else begin
					tick_count		<= 11'b0;
					rv_ethtype      <= 8'b0;
					flowid_pre_reg	<= 14'b0;
					rdreq			<= 1'b0;
					pug_state	    <= idle;
				end
			end
		endcase
	end
	
ASFIFO_8_16  ASFIFO_8_16_inst
(        
    .wr_aclr(~i_rst_n),                                         //Reset the all signal
    .rd_aclr(~i_rst_n),
    .data   (iv_gmii_data),                                         //The Inport of data 
    .rdreq  (rdreq),                                           //active-high
    .wrclk  (i_gmii_clk),                                          //ASYNC WriteClk(), SYNC use wrclk
    .rdclk  (i_clk),                                         //ASYNC WriteClk(), SYNC use wrclk  
    .wrreq  (i_gmii_en),                                          //active-high
    .q      (dcfifo_data),                              //The output of data
    .wrfull (),                              //Write domain full 
    .wralfull(),                                        //Write domain almost-full
    .wrempty(),                                     //Write domain empty
    .wralempty(),                                       //Write domain almost-full  
    .rdfull (),                                          //Read domain full
    .rdalfull(),                                        //Read domain almost-full   
    .rdempty(rdempty),                                        //Read domain empty
    .rdalempty(),                                       //Read domain almost-empty
    .wrusedw(),                                     //Write-usedword
    .rdusedw()          
    );	
	
endmodule